/**
 * AESUtil.java
 * 
 * Copyright(C)2008 UBA Corporation.
 * written by Founder Corp.
 */
package com.iori.common.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
/**
 * [クラス名]<br>
 * AESUtilクラス<br>
 * <br>
 * [機能概要]<br>
 * AES暗号復号機能を提供します。<br>
 * <br>
 * [変更履歴]<br>
 * 2010/3/2 ver1.00 新規作成<br>
 * <br>
 * 
 * @author FOUNDER CORPORATION
 */
public class AESUtil {

	/**
	 * 暗号化算法を定義する
	 */
	private static final String ALGORITHM = "AES";
	
	/**
	 * シークレットキーを定義する
	 */
	private static final String keyStr="gR1LXhu2JFvd9EHJ";

	/**
	 * 何もしないコンストラクタ。
	 */
	protected AESUtil() {
	}

	/**
	 * シークレットキー対象を新規作成する
	 * 
	 * @param strCustomKey
	 *            シークレットキーをカスタマイズする。 AES算法に対し、16||24||32のASCII文字を入力して下さい
	 * @return シークレットキー対象
	 */
	public static SecretKey createKey(String strCustomKey) {
		SecretKey desKey = null;
		try {
			desKey = new SecretKeySpec(strCustomKey.getBytes("UTF-8"),
					ALGORITHM);
		} catch (UnsupportedEncodingException e) {
		}
		return desKey;
	}

	/**
	 * データを暗号化
	 * 
	 * @param para
	 *            暗号化したいデータ
	 * @param deskey
	 *            シークレットキー
	 * @return 暗号文（バイト配列）
	 */
	public static byte[] encrypt(String para, String keyStr) {

		byte[] inputInfo = null;
		try {
			inputInfo = para.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e1) {
			
		}
		SecretKey desKey = createKey(keyStr);

		if (inputInfo == null)
			return null;

		Cipher c1 = null;

		try {
			c1 = Cipher.getInstance(ALGORITHM);

			try {
				c1.init(Cipher.ENCRYPT_MODE, desKey);
				try {
					byte[] cipherByte = c1.doFinal(inputInfo);
					return cipherByte;
				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IllegalBlockSizeException e) {
					e.printStackTrace();
				} catch (BadPaddingException e) {
					e.printStackTrace();
				}
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * データを復号化
	 * 
	 * @param cipherInfo
	 *            復号化したい暗号文（バイト配列）
	 * @param deskey
	 *            シークレットキー
	 * @return 原文（バイト配列）
	 */
	public static byte[] decrypt(byte[] cipherInfo, String keyStr) {
		if (cipherInfo == null)
			return null;

		Cipher c1 = null;
		SecretKey desKey = createKey(keyStr);
		try {
			c1 = Cipher.getInstance(ALGORITHM);
			try {
				c1.init(Cipher.DECRYPT_MODE, desKey);
				try {
					byte[] cipherByte = c1.doFinal(cipherInfo);
					return cipherByte;
				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IllegalBlockSizeException e) {
					e.printStackTrace();
				} catch (BadPaddingException e) {
					e.printStackTrace();
				}
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * データを暗号化
	 * 
	 * @param str
	 *          暗号化したい文（String）
	 *          
	 * @return 暗号化された文(length:44)
	 * 			
	 */
	public static String encrypt(String str) {
		if(null == str){
			return null;
		}
		
		String encryptStr = null;
		
		//AESで暗号化する
		byte[] enByte=encrypt(str,keyStr);
		
		//BASE64で再暗号化して、byteからStringに転換する
		encryptStr= new BASE64Encoder().encode(enByte);
		
		return encryptStr;
	}
	
	/**
	 * データを復号化
	 * 
	 * @param deStr
	 *            復号化したい暗号文（String）
	 *            
	 * @return 原文
	 */
	public static String decrypt(String deStr) {
		if(null == deStr){
			return null;
		}
		
		String decryptStr = null;
		
		byte[] enByte = null;;
		try {
			//BASE64で復号
			enByte = new BASE64Decoder().decodeBuffer(deStr);
			//AESで復号
			enByte=decrypt(enByte,keyStr);
			//Stringに転換
			decryptStr = new String(enByte, "UTF-8");
			
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		
		return decryptStr;
	}
	
}
